﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;

namespace TopologyWizzard
{
    public partial class Wizzard : Form
    {
        private List<Router> routers;
        private int selectedRouter;
        private int selectedInterface;
        private Image btmCE;
        private Image btmPE;
        private Image btmP;
        private Image btmI;
        private int which;
        private int selectedCombo;
        private int selectedRow;

        public Wizzard()
        {
            InitializeComponent();
            picBox.AllowDrop = true;
            routers = new List<Router>();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void btnImage_MouseDown(object sender, MouseEventArgs e)
        {
            which = 1;
            Button btnPic = (Button)sender;
            btnPic.DoDragDrop(btnPic.Image, DragDropEffects.Copy);
        }

        private void btnImage_MouseDown2(object sender, MouseEventArgs e)
        {
            which = 2;
            Button btnPic = (Button)sender;
            btnPic.DoDragDrop(btnPic.Image, DragDropEffects.Copy);
        }

        private void btnImage_MouseDown3(object sender, MouseEventArgs e)
        {
            which = 3;
            Button btnPic = (Button)sender;
            btnPic.DoDragDrop(btnPic.Image, DragDropEffects.Copy);
        }

        private void btnImage_MouseDown4(object sender, MouseEventArgs e)
        {
            which = 4;
            Button btnPic = (Button)sender;
            btnPic.DoDragDrop(btnPic.Image, DragDropEffects.Copy);
        }

        private void pictureBox_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.Bitmap))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void pictureBox_DragDrop(object sender, DragEventArgs e)
        {
            if (which == 1)
            {
                PictureBox picbox = (PictureBox)sender;
                int x = (int)Math.Round(((decimal)e.X / 120), 0) *120 - this.Location.X - 50;
                int y = (int)Math.Round(((decimal)e.Y / 80), 0) *80 - this.Location.Y - 80;
                Router r = new Router(x, y, which);
                r.Name = "CE";
                routers.Add(r);

                Graphics g = picbox.CreateGraphics();
                g.DrawImage((Image)e.Data.GetData(DataFormats.Bitmap), new Point(x, y));
                btmCE = (Image)e.Data.GetData(DataFormats.Bitmap);
            }

            if (which == 2)
            {
                PictureBox picbox = (PictureBox)sender;
                int x = (int)Math.Round(((decimal)e.X / 120), 0) * 120 - this.Location.X - 50;
                int y = (int)Math.Round(((decimal)e.Y / 80), 0) * 80 - this.Location.Y - 80;
                Router r = new Router(x, y, which);
                r.Name = "PE";
                routers.Add(r);

                Graphics g = picbox.CreateGraphics();
                g.DrawImage((Image)e.Data.GetData(DataFormats.Bitmap), new Point(x, y));
                btmPE = (Image)e.Data.GetData(DataFormats.Bitmap);
            }

            if (which == 3)
            {
                PictureBox picbox = (PictureBox)sender;
                int x = (int)Math.Round(((decimal)e.X / 120), 0) * 120 - this.Location.X - 50;
                int y = (int)Math.Round(((decimal)e.Y / 80), 0) * 80 - this.Location.Y - 80;
                Router r = new Router(x, y, which);
                r.Name = "P";
                routers.Add(r);

                Graphics g = picbox.CreateGraphics();
                g.DrawImage((Image)e.Data.GetData(DataFormats.Bitmap), new Point(x, y));
                btmP = (Image)e.Data.GetData(DataFormats.Bitmap);
            }

            if (which == 4)
            {
                PictureBox picbox = (PictureBox)sender;

                int x = e.X - this.Location.X - 30;
                int y = (int)Math.Round(((decimal)e.Y / 15), 0) * 15 - this.Location.Y - 80;

                int ok = 0;
                int rout = 0; int i = 0;
                foreach (Router r in routers)
                {
                       if ((x <= r.X + 70 && x >= r.X + 50) && (y <= r.Y + 60 && y >= r.Y))
                    {
                        ok = 1; rout = i;
                        x= r.X+70;
                    }
                    if( (x <= r.X -5  && x >= r.X - 25) && (y <= r.Y + 60 && y >= r.Y))
                    {
                        ok = 1; rout = i;
                        x = r.X - 20;
                    }
                    i++;
                }
                if (ok == 1)
                {
                    Interface inte = new Interface(x, y);
                    routers[rout].Interfaces.Add(inte);
                    
                    Graphics g = picbox.CreateGraphics();

                    g.DrawImage((Image)e.Data.GetData(DataFormats.Bitmap), new Point(x, y));
                    btmI = (Image)e.Data.GetData(DataFormats.Bitmap);
                }
          
            }

            which = 0;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            picBox.Image = null;
            picBox.Invalidate();
            routers.Clear();
            allLines.Clear();
            

            textBox1.Text = "";
            textBox1.Enabled = false;
            textBox2.Text = "";
            textBox2.Enabled = false;
        }

        private void picBox_MouseClick(object sender, MouseEventArgs e)
        {

            int x = e.X;
            int y = e.Y;
            int i = 0;
            int iss = 0;

                x = e.X - 30;
                y = e.Y - 30;

                foreach (Router r in routers)
                {
                    

                    for (int o = 0; o < r.Interfaces.Count; o++)
                    {
                        if ((x <= r.Interfaces[o].X - 5 && x >= r.Interfaces[o].X - 35) && (y <= r.Interfaces[o].Y - 5 && y >= r.Interfaces[o].Y - 35))
                        {
                            selectedInterface = o;
                            selectedRouter = i;
                            textBox3.Enabled = true;
                            textBox3.Text = r.Interfaces[o].Name;
                            iss = 1;
                        }
                    }
                    if (iss == 0)
                    {
                        textBox3.Enabled = false;
                        textBox3.Text = "";
                    }

 
                    if ((x <= r.X + 30 && x >= r.X - 30) && (y <= r.Y + 30 && y >= r.Y - 30))
                    {
                   
                        textBox1.Enabled = true;
                        textBox1.Text = r.IpAddress;
                        textBox2.Enabled = true;
                        textBox2.Text = r.Name;

                        selectedRouter = i;
                        return;
                    }
                    i++;
                }

                textBox1.Text = "";
                textBox1.Enabled = false;
                textBox2.Text = "";
                textBox2.Enabled = false;


        }

        private void button2_Click(object sender, EventArgs e)
        {
            routers[selectedRouter].IpAddress = textBox1.Text;
            routers[selectedRouter].Name = textBox2.Text;
            foreach (Router r in routers)
            {

                for (int o = 0; o < r.Interfaces.Count; o++)
                {
                    r.Interfaces[o].Connections.Clear();
                }

            }
        }

        public class Lines
        {
            public Point startPoint = new Point();
            public Point endPoint = new Point();

        }

        Lines l = new Lines();
        List<Lines> allLines = new List<Lines>();

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            //collect endPoint when mouse moved
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
            {
                l.endPoint = e.Location;
                //Line completed
                allLines.Add(l);
                this.picBox.Invalidate();
            }

        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {

            //collect startPoint when left mouse clicked
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
            {
                l = new Lines();
                l.startPoint = e.Location;
            }
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            foreach (Router r in routers)
            {
                switch (r.Which) {
                case 1: 
                    e.Graphics.DrawImage(btmCE, new Point(r.X, r.Y));
                    break;
                case 2:
                    e.Graphics.DrawImage(btmPE, new Point(r.X, r.Y));
                    break;
                case 3:
                    e.Graphics.DrawImage(btmP, new Point(r.X, r.Y));
                    break;
                };
            }
  
            foreach (var aLine in allLines)
            {
                int okStart = 0;
                int okStop = 0;
                
                int router1 = 0;
                int interface1 = 0;
                int router2 = 0;
                int interface2 = 0;
                int i = 0;
                foreach (Router r in routers)
                {
                    
                    for (int o = 0; o < r.Interfaces.Count; o++)
                    {
                        if ((aLine.startPoint.X <= r.Interfaces[o].X + 15 && aLine.startPoint.X >= r.Interfaces[o].X) && (aLine.startPoint.Y <= r.Interfaces[o].Y + 15 && aLine.startPoint.Y >= r.Interfaces[o].Y))
                        {
                            okStart = 1;
                            router1 = i;
                            interface1 = o;
                        }
                        
                    }
                    i++;
                }

                i = 0;
                foreach (Router r in routers)
                {
                    
                    for (int o = 0; o < r.Interfaces.Count; o++)
                    {
                        if ((aLine.endPoint.X <= r.Interfaces[o].X + 15 && aLine.endPoint.X >= r.Interfaces[o].X ) && (aLine.endPoint.Y <= r.Interfaces[o].Y + 15 && aLine.endPoint.Y >= r.Interfaces[o].Y ))
                        {
                            okStop = 1;
                            router2 = i;
                            interface2 = o;
                        }
                    }
                    i++;
                }
            //    if ((System.Math.Abs(aLine.endPoint.X - aLine.startPoint.X) < 50) && (System.Math.Abs(aLine.startPoint.Y - aLine.endPoint.Y) < 50)) okStart = 0;
               
                if (okStart == 1 && okStop == 1)
                {
                    Connection con1 = new Connection(routers[router2].Name, routers[router2].Interfaces[interface2].Name, routers[router2].Interfaces[interface2].X,routers[router2].Interfaces[interface2].Y);
                    Connection con2 = new Connection(routers[router1].Name, routers[router1].Interfaces[interface1].Name, routers[router1].Interfaces[interface1].X,routers[router1].Interfaces[interface1].Y);

                    e.Graphics.DrawLine(Pens.Red, aLine.startPoint, aLine.endPoint);
                    bool exist = false;
                    for (int u = 0; u < routers[router1].Interfaces[interface1].Connections.Count; u++)
                    {
                        if (routers[router1].Interfaces[interface1].Connections[u].RemoteInterfaceName == con1.RemoteInterfaceName && routers[router1].Interfaces[interface1].Connections[u].RemoteRouterName == con1.RemoteRouterName) exist = true;
                    }
                    for (int u = 0; u < routers[router2].Interfaces[interface2].Connections.Count; u++)
                    {
                        if (routers[router2].Interfaces[interface2].Connections[u].RemoteInterfaceName == con2.RemoteInterfaceName && routers[router2].Interfaces[interface2].Connections[u].RemoteRouterName == con2.RemoteRouterName) exist = true;
                    }
                        if(exist == false) {
                        routers[router1].Interfaces[interface1].Connections.Add(con1);
                  //      routers[router2].interfaces[interface2].connections.Add(con2);
                    }
                }
            }

            foreach (Router r in routers)
            {

            for (int o = 0; o < r.Interfaces.Count; o++)
            {
                e.Graphics.DrawImage(btmI, new Point(r.Interfaces[o].X, r.Interfaces[o].Y));
            }

            }


        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            for (int u = 0; u < dataGridView1.Rows.Count; u++)
            {
                try
                { routers[selectedCombo].TestCaseList[u].GetType = dataGridView1[1, u].Value.ToString(); }
                catch (NullReferenceException ex) { }
                try
                { routers[selectedCombo].TestCaseList[u].Oid = dataGridView1[2, u].Value.ToString(); }
                catch (NullReferenceException ex) { }
                try
                { routers[selectedCombo].TestCaseList[u].Description = dataGridView1[3, u].Value.ToString(); }
                catch (NullReferenceException ex) { }

            }

            if (selectedRow >= 0)
            {
                try
                {
                    routers[routersComboBox.SelectedIndex].TestCaseList[selectedRow].getExpectedAttr().Clear();
                }
                catch (ArgumentOutOfRangeException)
                {
                }

                for (int u = 0; u < dataGridView2.Rows.Count; u++)
                {
                    try
                    {
                        routers[routersComboBox.SelectedIndex].TestCaseList[selectedRow].getExpectedAttr().Add(Int32.Parse(dataGridView2[0, u].Value.ToString()), dataGridView2[1, u].Value.ToString());
                        routers[routersComboBox.SelectedIndex].TestCaseList[selectedRow].ResultAttr.Add(false);
                    }
                    catch (ArgumentException ex) { }
                }
            }

             SaveFileDialog saveFileDialog1 = new SaveFileDialog();   

				 String nazwaPliku="Topology";
				 nazwaPliku+=".vpn";

				 saveFileDialog1.FileName=nazwaPliku;
				 saveFileDialog1.DefaultExt = "*.vpn";
				 saveFileDialog1.Filter = "VPN Files|*.vpn";
				 if(saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
					 saveFileDialog1.FileName.Length > 0) 
				 {

					 Cursor = System.Windows.Forms.Cursors.WaitCursor;
                     Saver saver = new Saver();
                     saver.Set(routers);

					 String filename =  saveFileDialog1.FileName;

					 FileStream fs = new FileStream( filename, FileMode.Create );

					 BinaryFormatter formatter = new BinaryFormatter ();

					 formatter.Serialize( fs, saver );
					 fs.Close();


					 this.Cursor = System.Windows.Forms.Cursors.Default;	

					 MessageBox.Show("Zapisano pomyślnie!", "Zapisano pomyślnie!",
						 MessageBoxButtons.OK, MessageBoxIcon.Information);


				 }

        }

        private void button4_Click(object sender, EventArgs e)
        {
            routers[selectedRouter].Interfaces[selectedInterface].Name = textBox3.Text;

            foreach (Router r in routers)
            {

                for (int o = 0; o < r.Interfaces.Count; o++)
                {
                    r.Interfaces[o].Connections.Clear();
                }

            }
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            routersComboBox.Items.Clear();
            foreach (Router r in routers)
            {
                routersComboBox.Items.Add(r.Name);
            }
        }

        private void routersComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            splitContainer1.Panel2.Enabled = false;
            selectedRow = -1;

            for (int u = 0; u < dataGridView1.Rows.Count; u++)
            {
                try
                { routers[selectedCombo].TestCaseList[u].GetType = dataGridView1[1, u].Value.ToString(); } catch (NullReferenceException ex) { }
                try
                { routers[selectedCombo].TestCaseList[u].Oid = dataGridView1[2, u].Value.ToString(); } catch (NullReferenceException ex) { }
                try
                { routers[selectedCombo].TestCaseList[u].Description = dataGridView1[3, u].Value.ToString(); } catch (NullReferenceException ex) { }
                               
            }

           

            dataGridView1.Rows.Clear();
            dataGridView2.Rows.Clear();

            for (int i = 0; i < routers[routersComboBox.SelectedIndex].TestCaseList.Count;i++ )
            {
                dataGridView1.Rows.Add();
                dataGridView1[0, i].Value = i;
                dataGridView1[1, i].Value = routers[routersComboBox.SelectedIndex].TestCaseList[i].GetType;
                dataGridView1[2, i].Value = routers[routersComboBox.SelectedIndex].TestCaseList[i].Oid;
                dataGridView1[3, i].Value = routers[routersComboBox.SelectedIndex].TestCaseList[i].Description;
            }

            selectedCombo = routersComboBox.SelectedIndex;
        }

        private void dodaj_Click(object sender, EventArgs e)
        {
            dataGridView1.Rows.Add();
            dataGridView1[0, dataGridView1.Rows.Count - 1].Value = dataGridView1.Rows.Count - 1;

            TestCase test = new TestCase(routers[routersComboBox.SelectedIndex]);
            routers[routersComboBox.SelectedIndex].TestCaseList.Add(test);
            
        }

        private void dataGridView1_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            splitContainer1.Panel2.Enabled = true;

            if (selectedRow >= 0)
            {
                routers[routersComboBox.SelectedIndex].TestCaseList[selectedRow].getExpectedAttr().Clear();
                for (int u = 0; u < dataGridView2.Rows.Count; u++)
                {
                    try { routers[routersComboBox.SelectedIndex].TestCaseList[selectedRow].getExpectedAttr().Add(Int32.Parse(dataGridView2[0, u].Value.ToString()), dataGridView2[1, u].Value.ToString());
                        routers[routersComboBox.SelectedIndex].TestCaseList[selectedRow].ResultAttr.Add(false);
                    }
                    catch (ArgumentException ex) { }
                }
            }

            dataGridView2.Rows.Clear();
            int j=0;
            selectedRow = e.RowIndex;
            foreach (KeyValuePair<int, string> attr in routers[routersComboBox.SelectedIndex].TestCaseList[e.RowIndex].getExpectedAttr())
            {
                dataGridView2.Rows.Add();
                dataGridView2[0, j].Value = attr.Key;
                dataGridView2[1, j].Value = attr.Value;
                j++;
            }
        }

        private void button8_Click(object sender, EventArgs e)
        {
            dataGridView2.Rows.Add();
            dataGridView2[0, dataGridView2.Rows.Count - 1].Value = dataGridView2.Rows.Count - 1;
            dataGridView2[1, dataGridView2.Rows.Count - 1].Value = 0;
        }

        private void usun_Click(object sender, EventArgs e)
        {
            dataGridView1.Rows.Remove(dataGridView1.Rows[selectedRow]);
            routers[selectedCombo].TestCaseList.RemoveAt(selectedRow);
        }
    }
}
